#include "server/SoundCloudServer.hpp"
#include "server/Server.hpp"
#include "kit/container/ThreadSafeQueue.hpp"
#include "kit/container/ThreadSafeMap.hpp"
#include "kit/user/UserMap.hpp"
#include "kit/event/Event.hpp"
#include "kit/coordinator/Coordinator.hpp"
#include "exception/Exception.hpp"
#include "system/socket/Connection.hpp"
#include <iostream>
#include <vector>

namespace ServerServer
{
	SoundCloudServer::SoundCloudServer()
	{
		// create required resources
		_map = new KitUser::UserMap();
		_queue = new KitContainer::ThreadSafeQueue<KitEvent::Event*> ();
		_eventProcessor = new KitProcessor::EventProcessor(_queue);
		_userProcessor = new KitProcessor::UserProcessor(_map);
	}

	SoundCloudServer::~SoundCloudServer()
	{
		// free resources
		// clean queue
		while(!_queue->empty())
			delete _queue->pop();

		// clean man
		std::vector<std::string> aKeys = _map->keys();
		for(int i = 0; i < aKeys.size(); ++i)
		{
			delete _map->get(aKeys[i]);
		}

		delete _map;
		delete _queue;

		// delete processors
		delete _eventProcessor;
		delete _userProcessor;
	}

	void SoundCloudServer::start()
	{
		try
		{
			// create and run coordinator to synchronize between user/event server
			KitCoordinator::Coordinator aCoordinator(_queue, _map, 10);
			aCoordinator.run();

			// create and run server on proper ports
			Server aEventServer(9090, 20, _eventProcessor);
			Server aUserServer(9099, 20, _userProcessor);
			aEventServer.run();
			aUserServer.run();

			// block till event server works
			aEventServer.join();

			// when it stops kill remaining threads, as we won't receive anymore events
			aCoordinator.kill();
			aUserServer.kill();
		}
		catch (Exception::BaseException & aExcept)
		{
			std::cerr << "The server was stopped. Exception caught: " << aExcept.what() << std::endl;
		}
		catch (...)
		{
			std::cerr << "Uknown exception was caught. The server was stopped." << std::endl;
		}
	}

}
